package com.cn;

import com.google.zxing.*;
import com.google.zxing.common.*;
import com.google.zxing.client.j2se.*;
import com.google.zxing.qrcode.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.*;
import java.util.*;

public class LargeFileQrConverter {

    private static final int MAX_QR_SIZE = 1500; // 每个二维码最大存储字符数
    private static final String QR_FORMAT = "PNG"; // 二维码图片格式

    // 📌 1️⃣ 【大文件 → 多个二维码】
    public static void fileToQr(String filePath, String qrFolder) throws Exception {
        // 读取文件内容
        String content = new String(Files.readAllBytes(Paths.get(filePath)), "UTF-8");

        // Base64 编码（减少乱码）
        String encodedContent = Base64.getEncoder().encodeToString(content.getBytes());

        // 分割成多个 QR 码
        List<String> parts = splitString(encodedContent, MAX_QR_SIZE);

        // 确保 QR 码保存目录存在
        Files.createDirectories(Paths.get(qrFolder));

        // 生成多个二维码
        for (int i = 0; i < parts.size(); i++) {
            String qrData = i + "/" + parts.size() + ":" + parts.get(i); // 添加分片信息
            BitMatrix bitMatrix = new MultiFormatWriter().encode(qrData, BarcodeFormat.QR_CODE, 400, 400);
            Path qrPath = Paths.get(qrFolder, "part-" + (i + 1) + ".png");
            MatrixToImageWriter.writeToPath(bitMatrix, QR_FORMAT, qrPath);
            System.out.println("生成二维码：" + qrPath);
        }
    }

    // 📌 2️⃣ 【多个二维码 → 还原大文件】
    public static void qrToFile(String qrFolder, String outputFile) throws Exception {
        // 读取所有二维码图片
        File folder = new File(qrFolder);
        File[] qrFiles = folder.listFiles((dir, name) -> name.endsWith(".png"));
        if (qrFiles == null || qrFiles.length == 0) {
            throw new IOException("未找到二维码文件！");
        }

        // 解析二维码并排序
        TreeMap<Integer, String> dataParts = new TreeMap<>();
        for (File qrFile : qrFiles) {
            BufferedImage bufferedImage = ImageIO.read(qrFile);
            LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
            BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));

            // 解析二维码
            Result result = new MultiFormatReader().decode(binaryBitmap);
            String decodedText = result.getText();

            // 获取分片索引
            String[] splitData = decodedText.split(":", 2);
            String[] indexInfo = splitData[0].split("/");
            int index = Integer.parseInt(indexInfo[0]);
            int total = Integer.parseInt(indexInfo[1]);

            // 存储分片
            dataParts.put(index, splitData[1]);
            System.out.println("解析二维码：" + qrFile.getName());

            // 校验是否所有部分都解析完成
            if (dataParts.size() == total) {
                break;
            }
        }

        // 合并分片数据
        StringBuilder fullContent = new StringBuilder();
        for (String part : dataParts.values()) {
            fullContent.append(part);
        }

        // Base64 解码并写入文件
        String decodedContent = new String(Base64.getDecoder().decode(fullContent.toString()));
        Files.write(Paths.get(outputFile), decodedContent.getBytes());
        System.out.println("文件已还原：" + outputFile);
    }

    // 📌 3️⃣ 辅助方法：字符串分割
    private static List<String> splitString(String text, int chunkSize) {
        List<String> parts = new ArrayList<>();
        for (int i = 0; i < text.length(); i += chunkSize) {
            parts.add(text.substring(i, Math.min(text.length(), i + chunkSize)));
        }
        return parts;
    }

    public static void main(String[] args) throws Exception {
        String inputFile = "src/main/resources/large_file.txt"; // 📄 输入文件
        String qrFolder = "src/main/resources/qr_codes";        // 📁 二维码存储文件夹
        String restoredFile = "src/main/resources/restoredFiles/restored_large.txt"; // 📄 还原后的文件

        // 生成多个二维码
        //fileToQr(inputFile, qrFolder);

        // 还原文件
        qrToFile(qrFolder, restoredFile);
    }
}
